<script setup lang="ts">
import {onMounted, reactive, ref, watchEffect} from 'vue'
import type {Coach, AddAndEditCoach, PageCoach, PageResp} from "@/type/coach.ts";
import {createCoach, deleteCoach, getCoachById, getPageCoaches, updateCoach} from "@/api/coach";
import {ElMessage, ElMessageBox, type FormInstance, type FormRules, type UploadProps} from "element-plus";

// 查询-下拉框+输入框数据
const input = ref('')
const select = ref('1')

// 分页-当前页码+一页多少条数据+总数据量
const currentPage = ref(1)
const pageSize = ref(6)
const total = ref(20)

// 表格数据
const parentBorder = ref(false)
const tableData = ref<Coach[]>([
  {
    // 默认数据
    coachId: 1,
    coachName: '张三',
    gender: '男',
    contact: '12345678998',
    specialization: '未知',
    introduction: '未知',
    avatar: '未知',
    age: -1,
    createTime: '未知',
    updateTime: '未知'
  }
])

// 分页查询教练
const getPageCoach = async () => {
  const pageInfo: PageCoach = {
    coachId: select.value == '4' ? Number(input.value) : null,
    coachName: select.value == '1' ? input.value : '',
    contact: select.value == '2' ? input.value : '',
    specialization: select.value == '3' ? input.value : '',
    page: currentPage.value,
    pageSize: pageSize.value
  }
  console.log(pageInfo)
  const result: PageResp = await getPageCoaches(pageInfo)
  if (result.code == 1) {
    total.value = result.data.total
    tableData.value = result.data.records
  }
}

// 挂载时查询一次
onMounted(() => {
  console.log(currentPage.value, pageSize.value)
  getPageCoach()
})

// 监控查询变量-有变则重新查询
watchEffect(() => {
  getPageCoach()
})

// 删除教练
const delCoach = (id: number) => {
  ElMessageBox.confirm(
      '确定要删除此教练?',
      '警告',
      {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'warning',
        center: true,
      }
  )
      .then(async () => {
        try {
          const result = await deleteCoach(id); // 调用删除接口
          if (result.code === 1) {
            ElMessage({
              type: 'success',
              message: '删除成功',
            });
            await getPageCoach(); // 刷新列表
          } else {
            // 处理错误情况
            ElMessage({
              type: 'error',
              message: result.message || '删除失败，请稍后重试。',
            });
          }
        } catch (error) {
          // 捕获网络请求或其他异常
          ElMessage({
            type: 'error',
            message: '删除失败，请检查网络或稍后重试。',
          });
        }
      })
      .catch(() => {
        // 用户取消删除操作
        ElMessage({
          type: 'info',
          message: '删除取消',
        });
      });
};

// Dialog数据
const DialogVisible = ref(false)
const DialogTitle = ref('新增教练')
const addOrEdit = ref(1)  // Dialog是新增(0)还是修改(>0)即同时代表修改的教练id

// Dialog中表单数据
const DialogFormData = reactive<AddAndEditCoach>({
  coachId: -1,
  coachName: '',
  gender: '',
  contact: '',
  specialization: '',
  introduction: '',
  avatar: '',
  age: undefined,
})

const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
  if (rawFile.type == 'image/png' || rawFile.type == 'image/jpeg' || rawFile.type == 'image/gif') {
    if (rawFile.size < 4194304) {
      return true
    } else {
      ElMessage.error('上传文件必须小于 4M')
      return false
    }
  } else {
    ElMessage.error('上传文件必须是 png | img | gif')
    return false
  }
}

const handleAvatarSuccess: UploadProps['onSuccess'] = (response, uploadFile) => {
  DialogFormData.avatar = response.data
}

// 表单校验
const ruleFormRef = ref<FormInstance>()
// 规则
const checkInput = (rule: any, value: any, callback: any) => {
  if (value === '') {
    callback(new Error('不可为空,请输入...'))
  } else {
    callback()
  }
}
const validateContact = (rule: any, value: any, callback: any) => {
  if (!value) return callback()
  setTimeout(() => {
    if (value && !/^1[3-9]\d{9}$/.test(value)) {
      callback(new Error('请输入有效的中国大陆手机号'))
    } else {
      callback()
    }
  }, 500)
}
const checkAge = (rule: any, value: any, callback: any) => {
  if (!value) return callback()
  setTimeout(() => {
    if (!Number.isInteger(value)) {
      callback(new Error('请输入数字'))
    } else {
      if (value < 18 || value > 65) {
        callback(new Error('年龄不符'))
      } else {
        callback()
      }
    }
  }, 500)
}
const rules = reactive<FormRules<AddAndEditCoach>>({
  coachName: [{validator: checkInput, trigger: 'blur'}],
  gender: [],
  contact: [{validator: validateContact, trigger: 'blur'}],
  specialization: [{validator: checkInput, trigger: 'blur'}],
  introduction: [],
  avatar: [],
  age: [{validator: checkAge, trigger: 'blur'}]
})

// 新增教练
const addCoach = () => {
  DialogTitle.value = '新增教练'
  addOrEdit.value = 0

  // 先清空表单数据
  DialogFormData.coachName = ''
  DialogFormData.gender = ''
  DialogFormData.contact = ''
  DialogFormData.specialization = ''
  DialogFormData.introduction = ''
  DialogFormData.avatar = ''
  DialogFormData.age = undefined

  DialogVisible.value = true
}
// 修改教练
const editCoach = async (id: number) => {
  DialogTitle.value = '修改教练'
  addOrEdit.value = id

  // 先将数据回显至表单
  // 用addOrEdit.value查询
  // 调用查询单个教练api
  const result = await getCoachById(addOrEdit.value)
  if (result.code == 1) {
    DialogFormData.coachId = result.data.coachId
    DialogFormData.coachName = result.data.coachName
    DialogFormData.gender = result.data.gender
    DialogFormData.contact = result.data.contact
    DialogFormData.specialization = result.data.specialization
    DialogFormData.introduction = result.data.introduction
    DialogFormData.avatar = result.data.avatar
    DialogFormData.age = result.data.age
  }

  DialogVisible.value = true
}
// 提交Dialog中的表单，新增或者修改
const confirm = async () => {
  if (addOrEdit.value > 0) {
    const result = await updateCoach((DialogFormData as AddAndEditCoach))
    if (result.code == 1) {
      ElMessage.success('编辑成功')
    }
  } else {
    const addFormData: Omit<AddAndEditCoach, 'coachId'> = {
      coachName: DialogFormData.coachName,
      gender: DialogFormData.gender,
      contact: DialogFormData.contact,
      specialization: DialogFormData.specialization,
      introduction: DialogFormData.introduction,
      avatar: DialogFormData.avatar,
      age: DialogFormData.age,
    }
    const result = await createCoach(addFormData)
    if (result.code == 1) {
      ElMessage.success('新增成功')
    }
  }

  DialogVisible.value = false

  // 成功操作后更新表内容-再次分页查询
  await getPageCoach()
}
</script>

<template>
  <div class="course-container">
    <!--主要操作展示区-->
    <el-card>
      <div class="header-add-and-find">
        <!--左侧新增教练按钮-->
        <el-button type="primary" @click="addCoach">新增教练</el-button>
        <!--右侧查询教练按钮-->
        <el-input
            v-model="input"
            clearable
            prefix-icon="Search"
            style="max-width: 600px"
            placeholder="（实时搜索）请输入"
            class="input-with-select"
        >
          <template #prepend>
            <el-select v-model="select" placeholder="Select" style="width: 115px">
              <el-option label="姓名" value="1"/>
              <el-option label="手机号" value="2"/>
              <el-option label="专长" value="3"/>
              <el-option label="id" value="4"/>
            </el-select>
          </template>
        </el-input>
      </div>
      <div class="info-main">
        <el-table :data="tableData" :border="parentBorder" max-height="445" table-layout="fixed" style="width: 100%">
          <!--详细数据展开-->
          <el-table-column type="expand">
            <template #default="props">
              <div class="detail-info" style="display: flex; justify-content: center">
                <el-card
                    style="margin: 20px; width: 75%; border-radius: 12px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);">
                  <div style="display: flex;">
                    <!-- 左侧：头像 -->
                    <div
                        style="flex: 0 0 150px; display: flex; justify-content: center; align-items: center; padding: 20px;">
                      <el-avatar :size="120" :src="props.row.avatar" style="border: 2px solid #eee;"></el-avatar>
                    </div>
                    <!-- 右侧：详细信息 -->
                    <div style="flex: 1; padding: 20px;">
                      <h2 style="margin: 0 0 10px; font-size: 24px; color: #333;">{{ props.row.coachName }}</h2>
                      <div style="display: flex; flex-wrap: wrap; gap: 10px;">
                        <p style="margin: 0; font-size: 16px; color: #666;"><strong>ID:</strong> {{ props.row.coachId }}
                        </p>
                        <p style="margin: 0; font-size: 16px; color: #666;"><strong>性别:</strong> {{
                            props.row.gender
                          }}</p>
                        <p style="margin: 0; font-size: 16px; color: #666;"><strong>年龄:</strong> {{
                            props.row.age
                          }}</p>
                        <p style="margin: 0; font-size: 16px; color: #666;"><strong>联系方式:</strong>
                          {{ props.row.contact }}</p>
                        <p style="margin: 0; font-size: 16px; color: #666;"><strong>专长:</strong>
                          {{ props.row.specialization }}</p>
                      </div>
                      <p style="margin: 10px 0 0; font-size: 16px; color: #666;"><strong>介绍:</strong>
                        {{ props.row.introduction }}</p>
                      <div style="margin-top: 10px; font-size: 14px; color: #999;">
                        <p style="margin: 5px 0;"><strong>创建时间:</strong> {{ props.row.createTime }}</p>
                        <p style="margin: 5px 0;"><strong>更新时间:</strong> {{ props.row.updateTime }}</p>
                      </div>
                    </div>
                  </div>
                </el-card>
              </div>
            </template>
          </el-table-column>
          <!--表格展示-->
          <el-table-column label="ID" prop="coachId" align="center" width="100px"/>
          <el-table-column label="头像" align="center" width="150px">
            <template #default="props">
              <el-avatar :src="props.row.avatar"/>
            </template>
          </el-table-column>
          <el-table-column label="姓名" prop="coachName" align="center" width="150px"/>
          <el-table-column label="年龄" prop="age" align="center" width="150px"/>
          <el-table-column label="手机号" prop="contact" align="center" width="150px"/>
          <el-table-column label="专长" align="center" prop="specialization"/>
          <el-table-column label="操作" align="center">
            <template #default="props">
              <el-button type="primary" icon="Edit" color="#E6A23C" @click="editCoach(props.row.coachId)">修改
              </el-button>
              <el-button type="primary" icon="Delete" color="#F56C6C" @click="delCoach(props.row.coachId)">删除
              </el-button>
            </template>
          </el-table-column>
        </el-table>
        <!--分页-->
        <div class="pagination-block">
          <el-pagination
              v-model:current-page="currentPage"
              v-model:page-size="pageSize"
              :page-sizes="[6, 8, 10, 12, 14]"
              layout="prev, pager, next, jumper, ->,sizes, total"
              :total="total"
              :background="true"
          />
        </div>
      </div>
    </el-card>
    <!--Dialog-->
    <el-dialog
        v-model="DialogVisible"
        class="add-edit-dialog"
        width="500px"
        align-center
        :show-close="false"
    >
      <template #header>
        <div class="dialog-title">
          {{ DialogTitle }}
        </div>
      </template>
      <!-- 表单 -->
      <el-form
          ref="ruleFormRef"
          :model="DialogFormData"
          :rules="rules"
          label-width="100px"
          label-position="left"
          size="default"
          status-icon
          class="dialog-form"
      >
        <el-form-item label="姓名" prop="coachName">
          <el-input v-model="DialogFormData.coachName" placeholder="请输入姓名"/>
        </el-form-item>
        <el-form-item label="性别">
          <el-select
              v-model="DialogFormData.gender"
              placeholder="请选择性别"
              style="width: 100%"
          >
            <el-option label="秘密" value=""/>
            <el-option label="男" value="男"/>
            <el-option label="女" value="女"/>
            <el-option label="其他" value="其他"/>
          </el-select>
        </el-form-item>
        <el-form-item label="年龄" prop="age">
          <el-input v-model.number="DialogFormData.age" placeholder="请输入年龄"/>
        </el-form-item>
        <el-form-item label="联系方式" prop="contact">
          <el-input v-model="DialogFormData.contact" placeholder="请输入联系方式"/>
        </el-form-item>
        <el-form-item label="专长" prop="specialization">
          <el-input v-model="DialogFormData.specialization" placeholder="请输入专长"/>
        </el-form-item>
        <el-form-item label="介绍">
          <el-input
              v-model="DialogFormData.introduction"
              type="textarea"
              :rows="3"
              placeholder="请输入介绍"
          />
        </el-form-item>
        <el-form-item label="头像">
          <el-upload
              class="image-uploader"
              action="http://localhost:8080/files/upload"
              :data="{ type: 3 }"
              :show-file-list="false"
              :on-success="handleAvatarSuccess"
              :before-upload="beforeAvatarUpload"
          >
            <img v-if="DialogFormData.avatar" :src="DialogFormData.avatar" class="image"/>
            <el-icon v-else class="image-uploader-icon">
              <Plus/>
            </el-icon>
          </el-upload>
        </el-form-item>
      </el-form>
      <!-- 底部按钮 -->
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="DialogVisible = false">取消</el-button>
          <el-button type="primary" @click="confirm">提交</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<style scoped lang="scss">
.course-container {
  .header-add-and-find {
    margin-bottom: 25px;
    display: flex;
    justify-content: space-between;

    .input-with-select .el-input-group__prepend {
      background-color: var(--el-fill-color-blank);
    }
  }

  .info-main {
    .pagination-block {
      margin-top: 20px;
    }
  }

  .add-edit-dialog {
    border-radius: 12px;

    .dialog-title {
      text-align: center;
      font-weight: bold;
      font-size: 24px;
    }

    .dialog-form {
      padding: 20px;

      .image-uploader {
        display: flex;
        justify-content: center;
        align-items: center;
        border: 1px dashed #d9d9d9;
        border-radius: 6px;
        width: 100px;
        height: 100px;
        cursor: pointer;
        overflow: hidden;

        .image {
          width: 100%;
          height: 100%;
          object-fit: cover;
        }

        .image-uploader-icon {
          font-size: 24px;
          color: #8c939d;
        }

        &:hover {
          border-color: #409eff;
        }
      }
    }
  }
}
</style>

<style>
.image-uploader .el-upload {
  display: flex;
  justify-content: center;
  align-items: center;
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  width: 100px;
  height: 100px;
  cursor: pointer;
  overflow: hidden;
}

.image-uploader .el-upload:hover {
  border-color: #409eff;
}

.el-icon.image-uploader-icon {
  font-size: 24px;
  color: #8c939d;
}
</style>